﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;

namespace YArchitech.Temp
{
	public class HYPipeSpecifications : SortedSet<HYPipeSpecification>, IHYXmlSerial
	{
		public SortedSet<int> GetDNs()
		{
			return new SortedSet<int>(from sp in this
			select sp.DN);
		}

		public new bool Add(HYPipeSpecification item)
		{
			return item.IsValid && base.Add(item);
		}

		public HYPipeSpecification GetSpecification(int DN)
		{
			IEnumerable<HYPipeSpecification> enumerable = from sp in this
			where sp.DN == DN
			select sp;
			if (enumerable == null || enumerable.Count<HYPipeSpecification>() == 0)
			{
				return null;
			}
			return enumerable.First<HYPipeSpecification>();
		}

		public HYPipeSpecifications GetMatchSpecificationsByDNRange(Range dnRange)
		{
			HYPipeSpecifications hypipeSpecifications = new HYPipeSpecifications();
			hypipeSpecifications.UnionWith(from sp in this
			where dnRange.Contains((double)sp.DN)
			select sp);
			return hypipeSpecifications;
		}

		public bool SelectSpecificationByLoad(double load, out HYPipeSpecification spec)
		{
			spec = null;
			if (base.Count == 0)
			{
				return false;
			}
			double num = double.MaxValue;
			foreach (HYPipeSpecification hypipeSpecification in this)
			{
				if (hypipeSpecification.LoadRange.Contains(load))
				{
					spec = hypipeSpecification;
					return true;
				}
				double minDistance = hypipeSpecification.LoadRange.GetMinDistance(load);
				if (num > minDistance)
				{
					num = minDistance;
					spec = hypipeSpecification;
				}
			}
			return false;
		}

		public bool SelectSpecificationByVelocity(double flow, out HYPipeSpecification spec)
		{
			spec = null;
			if (base.Count == 0)
			{
				return false;
			}
			if (Utility.IsZero(flow, 1E-05))
			{
				spec = this.First<HYPipeSpecification>();
				return false;
			}
			double num = double.MaxValue;
			foreach (HYPipeSpecification hypipeSpecification in this)
			{
				double velocity = hypipeSpecification.GetVelocity(flow);
				if (hypipeSpecification.VelocityRange.Contains(velocity))
				{
					spec = hypipeSpecification;
					return true;
				}
				double minDistance = hypipeSpecification.VelocityRange.GetMinDistance(velocity);
				if (num > minDistance)
				{
					num = minDistance;
					spec = hypipeSpecification;
				}
			}
			return false;
		}

		public virtual void WriteXml(XElement xe)
		{
			foreach (HYPipeSpecification hypipeSpecification in this)
			{
				XElement xelement = new XElement("Specification");
				hypipeSpecification.WriteXml(xelement);
				xe.Add(xelement);
			}
		}

		public virtual void ReadXml(XElement xe)
		{
			this.Clear();
			foreach (XElement xe2 in xe.Elements("Specification"))
			{
				HYPipeSpecification hypipeSpecification = new HYPipeSpecification();
				hypipeSpecification.ReadXml(xe2);
				this.Add(hypipeSpecification);
			}
		}
	}
}
